﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Configuration;
using System.Data;
using System.Linq;
using DapperExtensions;
using DapperExtensions.Predicate;

namespace LS.Cores
{

    public static class AttributeExtensions
    {
        public static TValue GetAttributeValue<TAttribute, TValue>(
            this Type type,
            Func<TAttribute, TValue> valueSelector)
            where TAttribute : Attribute
        {
            var att = type.GetCustomAttributes(
                typeof(TAttribute), true
            ).FirstOrDefault() as TAttribute;
            if (att != null)
            {
                return valueSelector(att);
            }
            return default(TValue);
        }
    }
    public sealed class DapperHelper
    {

        /// <summary>
        /// 根据ID获得实体对象
        /// </summary>
        /// <param name="id">要查询对象的ID</param>
        /// <param name="conString">数据库连接字符串</param>
        /// <returns></returns>
        public static T GetById<T>(dynamic id, ConnectionStringSettings conString = null) where T : class
        {
            using (IDbConnection cn = DbConnectionFactory.Instance.GetOpenConnection(conString))
            {
                cn.Open();
                var tblName = typeof(T).GetAttributeValue((TableAttribute ta) => ta.Name);
                T t = SqlHelper.QueryOne<T>($"select *from {tblName} where id={id}");
                //  T t = cn.Get<T>(id as object);
                cn.Close();
                return t;
            }
        }
        /// <summary>
        /// 查询列表数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="predicate"></param>
        /// <param name="sort"></param>
        /// <returns></returns>
        public static IEnumerable<T> GetList<T>(object predicate = null, IList<ISort> sort = null, ConnectionStringSettings conString = null) where T : class
        {
            using (IDbConnection cn = DbConnectionFactory.Instance.GetOpenConnection(conString))
            {
                cn.Open();
                var t = cn.GetList<T>(predicate, sort);
                cn.Close();
                return t;
            }
        }

        /// <summary>
        /// 查询列表数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="predicate"></param>
        /// <param name="sort"></param>
        /// <returns></returns>
        public static IList<T> Query<T>(string sql = null, ConnectionStringSettings conString = null) where T : class
        {
            var tblName = typeof(T).GetAttributeValue((TableAttribute ta) => ta.Name);
        
            using (IDbConnection cn = DbConnectionFactory.Instance.GetOpenConnection(conString))
            {
                cn.Open();
                var wheresql = "select * from " + tblName + " where 1=1 " + sql;
                var t = SqlHelper.Query<T>(wheresql, conString).ToList();
                cn.Close();
                return t;
            }
        }

        /// <summary>
        /// 根据多个Id获取多个实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ids"></param>
        /// <returns></returns>
        public static IEnumerable<T> GetByIds<T>(IList<dynamic> ids, ConnectionStringSettings conString = null)
        {
            var tblName = typeof(T).GetAttributeValue((TableAttribute ta) => ta.Name);
            var idsin = string.Join(",", ids.ToArray<dynamic>());
            var sql = "SELECT * FROM @table WHERE Id in (@ids)";


            using (IDbConnection cn = DbConnectionFactory.Instance.GetOpenConnection(conString))
            {
                cn.Open();
                var dataList = SqlHelper.Query<T>(sql, new { table = tblName, ids = idsin }).ToList();
                cn.Close();
                return dataList;
            }
        }
        /// <summary>
        /// 统计记录总数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public int Count<T>(object predicate, ConnectionStringSettings conString = null) where T : class
        {
            using (IDbConnection cn = DbConnectionFactory.Instance.GetOpenConnection(conString))
            {
                cn.Open();
                var t = cn.Count<T>(predicate);
                cn.Close();
                return t;
            }
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="allRowsCount"></param>
        /// <param name="predicate"></param>
        /// <param name="sort"></param>
        /// <returns></returns>
        public static PageDataView<T> GetPageData<T>(int pageIndex, int pageSize, string strwhere, string table = null, string fields = "*", string primaryKey = "id",
             string sort = "id", ConnectionStringSettings conString = null) where T : class
        {
            if (table == null)
                table = typeof(T).GetAttributeValue((TableAttribute ta) => ta.Name);
            PageCriteria criteria = new PageCriteria();
            criteria.Condition = "1=1";
            if (!string.IsNullOrEmpty(strwhere))
            {
                criteria.Condition += strwhere;
            }
            criteria.CurrentPage = pageIndex;
            criteria.Fields = fields;
            criteria.PageSize = pageSize;
            criteria.TableName = table;
            criteria.PrimaryKey = primaryKey;
            criteria.Sort = sort;
            return SqlHelper.GetPageData<T>(criteria, conString);

        }



        /// <summary>
        /// 新增对象，返回对象的id
        /// </summary>
        /// <param name="t"></param>
        /// <param name="conString"></param>
        /// <returns></returns>
        public static long Insert<T>(T t, ConnectionStringSettings conString = null) where T : class
        {
            long id = 0;
            using (IDbConnection cn = DbConnectionFactory.Instance.GetOpenConnection(conString))
            {
                cn.Open();
                id = cn.Insert(t);
                cn.Close();
            }
            return id;
        }
       
        /// <summary>
        /// 更新单个对象
        /// </summary>
        /// <param name="t">要更新的对象</param>
        /// <param name="conString"></param>
        /// <returns></returns>
        public static bool Update<T>(T t, ConnectionStringSettings conString = null) where T : class
        {
            bool isSuccess = false;
            using (IDbConnection cn = DbConnectionFactory.Instance.GetOpenConnection(conString))
            {
                cn.Open();
                isSuccess = cn.Update(t);
                cn.Close();
            }
            return isSuccess;
        }
        /// <summary>
        /// 根据id删除对象
        /// </summary>
        /// <param name="id">要删除对象的id</param>
        /// <param name="conString"></param>
        /// <returns></returns>

        public  static  bool Delete<T>(string ids, ConnectionStringSettings conString = null) where T : class
        {
            var tblName = typeof(T).GetAttributeValue((TableAttribute ta) => ta.Name);
            var result = 0;
            var arryid = ids.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            if (arryid.Length == 1)
            {
                string sql = "update     " + tblName + " set IsDel=1  where id=@Id";
                using (IDbConnection cn = DbConnectionFactory.Instance.GetOpenConnection(conString))
                {
                    cn.Open();
                    result = SqlHelper.Execute(sql, new { Id = arryid[0] });
                    cn.Close();
                }
            }
            else
            {                
                string sql = "update     " + tblName + " set IsDel=1  where id in ("+ids.TrimEnd(',')+")";
                using (IDbConnection cn = DbConnectionFactory.Instance.GetOpenConnection(conString))
                {
                    cn.Open();
                    result = SqlHelper.Execute(sql);
                    cn.Close();
                }
            }
            return result > 0;
        }
        /// <summary>
        /// 根据id恢复对象
        /// </summary>
        /// <param name="id">要删除对象的id</param>
        /// <param name="conString"></param>
        /// <returns></returns>

        public static bool Recovery<T>(string ids, ConnectionStringSettings conString = null) where T : class
        {
            var tblName = typeof(T).GetAttributeValue((TableAttribute ta) => ta.Name);
            var result = 0;
            var arryid = ids.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            if (arryid.Length == 1)
            {
                string sql = "update     " + tblName + " set IsDel=0  where id=@Id";
                using (IDbConnection cn = DbConnectionFactory.Instance.GetOpenConnection(conString))
                {
                    cn.Open();
                    result = SqlHelper.Execute(sql, new { Id = arryid[0] });
                    cn.Close();
                }
            }
            else
            {
                string sql = "update     " + tblName + " set IsDel=0  where id in ("+ids+")";
                using (IDbConnection cn = DbConnectionFactory.Instance.GetOpenConnection(conString))
                {
                    cn.Open();
                    result = SqlHelper.Execute(sql);
                    cn.Close();
                }
            }
            return result > 0;
        }
        /// <summary>
        /// 根据id彻底删除对象
        /// </summary>
        /// <param name="id">要删除对象的id</param>
        /// <param name="conString"></param>
        /// <returns></returns>

        public static bool Remove<T>(string ids, ConnectionStringSettings conString = null) where T : class
        {
            var tblName = typeof(T).GetAttributeValue((TableAttribute ta) => ta.Name);
            var result = 0;
            var arryid = ids.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            if (arryid.Length == 1)
            {
                string sql = "delete from      " + tblName + "   where id=@Id";
                using (IDbConnection cn = DbConnectionFactory.Instance.GetOpenConnection(conString))
                {
                    cn.Open();
                    result = SqlHelper.Execute(sql, new { Id = arryid[0] });
                    cn.Close();
                }
            }
            else
            {
                string sql = "delete from        " + tblName + "   where id in (@Id)";
                using (IDbConnection cn = DbConnectionFactory.Instance.GetOpenConnection(conString))
                {
                    cn.Open();
                    result = SqlHelper.Execute(sql, new { Id = ids });
                    cn.Close();
                }
            }
            return result > 0;
        }

    }
}
